<script lang="ts">
  import { heightData } from '@/constants/data';
  import { GENDER } from '@/enum/user';
  import { useStore } from '@/store';
  import { UserModule } from '@/store/modules/user.module';
  import { computed, defineComponent, ref, watch } from '@vue/composition-api';
  import OtoPicker, { PropsType } from './components/oto-picker.vue';
  import OtoSelect from './components/oto-select.vue';
  import OtoButton from '@/components/common/oto-button.vue';
  import OtoAvatar from './components/oto-avatar.vue';
  import { submitUserMessage, StudyMatchUserMessge, getUserMessage } from '@/api/study-match';
  import { onLoad } from '@/hooks/uniapp-composition-hooks';
  import { useRouter } from '@/constants/router';
  import { Message } from '@/libs';

  export default defineComponent({
    components: {
      OtoPicker,
      OtoSelect,
      OtoButton,
      OtoAvatar
    },
    setup() {
      const router = useRouter();
      type StyleInLine = 'placeholder';

      type ListItemType = {
        type: 'image' | 'text' | 'input' | 'select' | 'picker';
        label: string;
        prop: string;
        mode?: PropsType['mode'];
        selectList?: Array<any>;
        showPickStatus?: boolean;
        style?: Record<StyleInLine, string | number> & Record<string, any>;
        hooks?: Record<string, Function>;
      };

      const list = ref<ListItemType[]>([
        // {
        //   type: 'image',
        //   label: '头像',
        //   prop: 'avatarUrl'
        // },
        // {
        //   type: 'input',
        //   label: '昵称',
        //   prop: 'nickName',
        //   style: {
        //     placeholder: '请输入昵称'
        //   }
        // },
        {
          type: 'select',
          label: '性别',
          prop: 'sex',
          selectList: [
            {
              label: '小哥哥',
              value: GENDER.BOY
            },
            {
              label: '小姐姐',
              value: GENDER.GIRL
            }
          ],
          style: {
            placeholder: '请选择性别',
            textFilter(value: number, item: ListItemType) {
              const optionsObejct = item.selectList?.find((selectItem) => {
                return selectItem.value === value;
              });
              return (optionsObejct && optionsObejct.label) || getStyleProperties(item.style, 'placeholder');
            }
          }
        },
        {
          type: 'picker',
          mode: 'date',
          label: '生日',
          prop: 'birthday',
          showPickStatus: false,
          style: {
            placeholder: '请选择生日'
          }
        },
        {
          type: 'picker',
          label: '所在地',
          mode: 'region',
          prop: 'nowStay',
          showPickStatus: true,
          style: {
            placeholder: '请选择所在地',
            pickerFilter(item: ListItemType) {
              if (userData.value[item.prop as keyof StudyMatchUserMessge]) {
                return (userData.value[item.prop as keyof StudyMatchUserMessge] as string).split('，');
              }
              return [];
            }
          }
        },
        {
          type: 'select',
          label: '身高（mm）',
          prop: 'height',
          selectList: heightData,
          style: {
            placeholder: '选择身高'
          }
        },
        {
          type: 'picker',
          mode: 'region',
          label: '家乡',
          prop: 'home',
          style: {
            placeholder: '请选择家乡',
            pickerFilter(item: ListItemType) {
              if (userData.value[item.prop as keyof StudyMatchUserMessge]) {
                return (userData.value[item.prop as keyof StudyMatchUserMessge] as string).split('，');
              }
              return [];
            }
          }
        },
        {
          type: 'input',
          label: '手机号',
          prop: 'phone',
          style: {
            placeholder: '请输入手机号'
          }
        },
        {
          type: 'select',
          label: '学院',
          prop: 'college',
          selectList: [
            {
              label: '数学与计算机学院',
              value: '数学与计算机学院'
            },
            {
              label: '旅游学院',
              value: '旅游学院'
            },
            {
              label: '文教院',
              value: '文教院'
            }
          ],
          style: {
            placeholder: '请选择你的学院'
          }
        }
      ]);

      const tags = ref<string[]>([]);

      const userModule = useStore(UserModule);

      const userInfo = computed(() => {
        return userModule.getUserInfo;
      });

      const userData = ref<StudyMatchUserMessge>({
        id: 0,
        userId: 0,
        sex: 0,
        age: 0,
        height: 0,
        home: '',
        phone: '',
        personalTips: '',
        birthday: '',
        college: '',
        nowStay: ''
      });

      const formItemType: Record<ListItemType['type'], ListItemType['type']> = {
        image: 'image',
        input: 'input',
        select: 'select',
        picker: 'picker',
        text: 'text'
      };

      const tagList = ref(['高富帅', '高', '瘦', '白富美', '喜欢看电影', '高颜值', '爱学习']);

      const tagsShow = ref(false);

      watch(
        tags, // 注意这里
        (val) => {
          userData.value.personalTips = val.join('，');
        },
        {
          deep: true, // 深度监听
          immediate: true // 立即执行
        }
      );

      watch(
        () => userData.value.birthday, // 注意这里
        (val) => {
          const birthYear = val?.split('-')[0];
          const nowDate = new Date();
          userData.value.age = nowDate.getFullYear() - Number(birthYear);
        },
        {
          deep: true, // 深度监听
          immediate: true // 立即执行
        }
      );

      function openTagsSelect() {
        tagsShow.value = true;
      }

      function getStyleProperties(style: Record<string, any> | undefined, prop: string) {
        return style?.[prop] || '';
      }

      function getStylePropertiesFunction(item: ListItemType | undefined, prop: string) {
        const style = item?.style;
        const excute = style?.[prop] || (() => {});
        return excute(item);
      }

      function select(item: string) {
        if (isSelect(item)) {
          tags.value = tags.value.filter((tagsItem) => tagsItem !== item);
        } else {
          tags.value.push(item);
        }
      }

      function isSelect(item: string) {
        return tags.value.includes(item);
      }

      function submit() {
        submitUserMessage(userData.value).then(async () => {
          await Message.success('提交成功');
          router.navigateBack({
            delta: 1
          });
        });
      }

      onLoad(() => {
        getUserMessage().then((res) => {
          const { data } = res;
          if (data) {
            userData.value = data;
            tags.value = data.personalTips.split('，');
          }
        });
      });

      return {
        tagList,
        list,
        tags,
        userInfo,
        userData,
        formItemType,
        tagsShow,
        getStyleProperties,
        getStylePropertiesFunction,
        submit,
        isSelect,
        select,
        openTagsSelect
      };
    }
  });
</script>

<template>
  <view class="message">
    <view class="top">
      <view class="point"></view>
      <view class="text">完善资料-决定你匹配的质量</view>
      <oto-button
        :customStyle="{
          width: '140rpx',
          height: '50rpx',
          fontSize: '24rpx',
          marginLeft: '30rpx',
          borderRadius: '12rpx'
        }"
        @click.stop="submit"
      >
        提交
      </oto-button>
    </view>
    <view class="list">
      <template v-for="(item, index) in list">
        <view class="list-item" :key="index">
          <view class="label">{{ item.label }}</view>
          <!-- <view class="value"> {{ userData[item.prop] }} </view> -->
          <view class="value">
            <input
              :placeholder="getStyleProperties(item.style, 'placeholder')"
              class="input"
              v-if="item.type === formItemType['input']"
              :type="getStyleProperties(item.style, 'type') || 'text'"
              v-model="userData[item.prop]"
            />
            <template v-if="item.type === formItemType['picker']">
              <view class="oto-picker">
                <oto-picker
                  :mode="item.mode"
                  :default-value="getStylePropertiesFunction(item, 'pickerFilter')"
                  v-model="userData[item.prop]"
                  :start="getStyleProperties(item.style, 'startDate')"
                  :end="getStyleProperties(item.style, 'endDate')"
                >
                  {{ userData[item.prop] || getStyleProperties(item.style, 'placeholder') }}
                </oto-picker>
              </view>
            </template>
            <template v-if="item.type === formItemType['select']">
              <view class="oto-select">
                <oto-select :select-value="userData[item.prop]" v-model="userData[item.prop]" :list="item.selectList">
                  {{
                    (getStyleProperties(item.style, 'textFilter') &&
                      getStyleProperties(item.style, 'textFilter')(userData[item.prop], item)) ||
                    userData[item.prop] ||
                    getStyleProperties(item.style, 'placeholder')
                  }}
                </oto-select>
              </view>
            </template>

            <template v-if="item.type === formItemType['image']">
              <oto-avatar v-model="userData[item.prop]" :src="userData[item.prop]" />
            </template>

            <template v-if="item.type === formItemType['text']">
              <view class="text">
                {{ userData[item.prop] || getStyleProperties(item.style, 'placeholder') }}
              </view>
            </template>
          </view>
        </view>
      </template>
    </view>
    <view class="tags">
      <view class="title"> 我的标签 </view>
      <view class="tags-list" @click.stop="openTagsSelect">
        <view class="tags-tips">#</view>
        <view class="tags-select-placeholder" v-if="tags.length === 0"> 请选择您的标签 </view>
        <template v-for="(item, index) in tags">
          <view class="tags-item" :key="index">
            {{ item }}
          </view>
        </template>
      </view>
    </view>
    <u-popup v-model="tagsShow" mode="bottom">
      <view class="tags-select">
        <view class="title"> 我的标签 </view>
        <template v-for="(item, index) in tagList">
          <view
            class="tags-item"
            :class="{
              selected: isSelect(item)
            }"
            :key="index"
            @click.stop="select(item)"
          >
            {{ item }}
          </view>
        </template>
      </view>
    </u-popup>
  </view>
</template>

<style lang="scss" scoped>
  .message {
    background-color: #eeeeee;
    min-height: 100vh;
    .top {
      padding: 20rpx 30rpx 20rpx 30rpx;
      display: flex;
      align-items: center;

      .point {
        width: 18rpx;
        height: 18rpx;
        background-color: #e48139;
        border-radius: 50%;
      }

      .text {
        font-size: 30rpx;
        margin-left: 20rpx;
        margin-right: 100rpx;
      }
    }
    .list {
      margin-bottom: 2vh;
      background: #fff;

      .list-item {
        width: 92%;
        height: 7vh;
        line-height: 7vh;
        margin: 0 auto;
        border-bottom: 2rpx solid #eeeeee;
        display: flex;
        justify-content: space-between;

        .label {
          width: 30%;
          height: 100%;
          float: left;
          color: #0e0454;
          font-weight: bold;
        }

        .value {
          width: 78%;
          height: 100%;
          display: flex;
          align-items: center;
          justify-content: flex-end;

          .input {
            text-align: right;
          }
        }
      }
    }

    .tags {
      width: 100%;
      background-color: #fff;
      margin-bottom: 2vh;
      box-shadow: 2rpx 2rpx 4vw 1rpx rgb(221, 221, 221);

      .title {
        width: 92%;
        height: 7vh;
        line-height: 7vh;
        margin: 0 auto;
        border-bottom: 2rpx solid #eeeeee;
        color: #ef8699;
      }

      .tags-list {
        display: flex;
        align-items: center;
        width: 92%;
        height: 7vh;
        margin: 0 auto;
        border-bottom: 2rpx solid #eeeeee;

        .tags-tips {
          color: #7457ca;
          font-size: 32rpx;
          display: inline;
        }
        .tags-item {
          font-size: 22rpx;
          display: inline-block;
          padding: 0 20rpx 0 20rpx;
          height: 60rpx;
          line-height: 60rpx;
          text-align: center;
          background-color: #f2f1fc;
          color: #7457ca;
          border-radius: 40rpx;
          margin-left: 20rpx;
        }
      }
    }

    .tags-select {
      height: 50vh;
      padding: 40rpx;
      margin-left: -30rpx;
      margin-top: -40rpx;

      .title {
        width: 92%;
        height: 7vh;
        line-height: 7vh;
        margin: 0 auto;
        border-bottom: 2rpx solid #eeeeee;
        color: #ef8699;
      }

      .tags-item {
        font-size: 22rpx;
        display: inline-block;
        padding: 0 20rpx 0 20rpx;
        height: 60rpx;
        line-height: 60rpx;
        text-align: center;
        background-color: #f2f1fc;
        color: #7457ca;
        border-radius: 40rpx;
        margin-left: 30rpx;
        margin-top: 40rpx;
      }

      .selected {
        background-color: #5d4be6;
        color: #fff;
      }
    }
  }
</style>
